package com.ds.esd.bpm.custom.routeto.reader;

import com.alibaba.fastjson.annotation.JSONField;
import com.ds.bpm.client.ActivityDef;
import com.ds.bpm.client.ActivityDefRight;
import com.ds.bpm.engine.WorkflowClientService;
import com.ds.config.TreeListResultModel;
import com.ds.esd.custom.api.annotation.APIEventAnnotation;
import com.ds.esd.custom.enums.CustomMenuItem;
import com.ds.esd.dsm.domain.annotation.BpmDomain;
import com.ds.esd.dsm.domain.enums.BpmDomainType;
import com.ds.esd.util.TreePageUtil;
import com.ds.jds.core.esb.EsbUtil;
import com.ds.org.Org;
import com.ds.org.Person;
import com.ds.server.OrgManagerFactory;
import com.ds.web.annotation.Aggregation;
import com.ds.web.annotation.AggregationType;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;

import java.util.*;

@Controller
@RequestMapping("/bpm/routeto/select/")
@BpmDomain(type = BpmDomainType.bpmright)
@Aggregation(type = AggregationType.customDomain, rootClass = ReaderPersonTreeService.class)
public class ReaderPersonTreeService {

    @APIEventAnnotation(bindMenu = CustomMenuItem.loadChild)
    @RequestMapping(method = RequestMethod.POST, value = "ReaderChildOrg")
    @ResponseBody
    public TreeListResultModel<List<ReaderOrgTree>> getReaderChildOrg(String nextActivityDefId, String orgId) {
        TreeListResultModel<List<ReaderOrgTree>> orgTreeResultModule = new TreeListResultModel<>();
        List<Object> activityTrees = new ArrayList<>();
        ActivityDef activityDef = null;
        try {
            Org org = OrgManagerFactory.getOrgManager().getOrgByID(orgId);
            activityDef = this.getClient().getActivityDef(nextActivityDefId);
            ActivityDefRight activityDefRight = activityDef.getRightAttribute();
            List<Person> performPersonList = activityDefRight.getReaderPersons();
            List<Person> personList = org.getPersonList();
            List<Org> performOrgs = getAllOrg(performPersonList, orgId);
            Collections.sort(personList);
            for (Person person : personList) {
                if (performPersonList.contains(person)) {
                    activityTrees.add(person);
                }
            }
            List<Org> childOrgs = org.getChildrenList();
            Collections.sort(childOrgs);
            for (Org childOrg : childOrgs) {
                if (performOrgs.contains(childOrg)) {
                    activityTrees.add(childOrg);
                }
            }
            orgTreeResultModule = TreePageUtil.getTreeList(activityTrees, ReaderOrgTree.class);
        } catch (Exception e) {
            e.printStackTrace();
        }

        return orgTreeResultModule;
    }


    private List<Org> getAllOrg(List<Person> personList, String topOrgId) {
        Map orgMap = new HashMap();
        List<Org> allOrgs = new ArrayList<Org>();
        for (int i = 0; i < personList.size(); i++) {
            Person perosn = (Person) personList.get(i);
            List<Org> orgs = perosn.getOrgList();
            if (orgs != null) {
                for (Org org : orgs) {
                    if (!orgMap.containsKey(org.getOrgId())) {
                        addOrg(orgMap, org, topOrgId);
                    }
                }
            }
        }
        allOrgs.addAll(orgMap.values());
        return allOrgs;
    }


    /**
     * @param map
     * @param org
     */
    private Map<String, Org> addOrg(Map<String, Org> map, Org org, String topOrgId) {
        if (org != null) {
            map.put(org.getOrgId(), org);
            Org parent = org.getParent();
            if (parent != null) {
                if (topOrgId != null && org.getOrgId().equals(topOrgId)) {
                    map.put(parent.getOrgId(), parent);
                } else {
                    if (!map.containsKey(parent.getOrgId())) {
                        addOrg(map, parent, topOrgId);
                    }
                }

            }

        }
        return map;

    }

    /**
     * @return
     */
    @JSONField(serialize = false)
    private WorkflowClientService getClient() {
        WorkflowClientService client = EsbUtil.parExpression("$BPMC", WorkflowClientService.class);        return client;
    }
}
